﻿
namespace n_SimulateObj
{
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using n_MainSystemData;
using n_GUIcoder;
using n_CPU;

//*****************************************************
//仿真对象类
public class SimulateObj
{
	//串口接收事件(仿真时由硬件发送)
	public delegate void D_PortValue( int d );
	public static D_PortValue delePortValue;
	
	//串口发送事件(仿真时由硬件接收)
	public delegate int D_PortRead();
	public static D_PortRead delePortRead;
	
	//串口开启事件(仿真)
	public delegate void D_OpenUart();
	public static D_OpenUart deleOpenUart;
	
	n_HardModule.HardModule owner;
	int ID;
	
	//坐标是相对于模块的中心位置 MidX, MidY
	public float X;
	public float MidX {
		set {
			X = value - this.Width / 2;
		}
		get { return X + this.Width / 2; }
	}
	
	public float Y;
	public float MidY {
		set {
			Y = value - this.Height / 2;
		}
		get { return Y + this.Height / 2; }
	}
	
	public float Width;
	public float Height;
	
	public int SimType;
	
	public const int IO_START = 50;
	public const int IO_END = 99;
	
	public const int LED = 0;
	public const int T_Beep = 3;
	public const int T_TimeDate = 7;
	public const int T_Uart = 9;
	public const int T_DataDisplay = 10;
	public const int T_SimLocate = 11;
	public const int T_Dot12864 = 12;
	public const int T_MultData = 13;
	public const int T_Arduino = 14;
	public const int T_16X32 = 15;
	
	public const int T_LD3320 = 17;
	public const int T_String = 18;
	
	//DataList[0]: 灯带数目N (缓冲字节数量为 3 * N
	public const int T_RGB_Array = 19;
	
	//DataList[0]: 灯环数目N (缓冲字节数量为 3 * N
	public const int T_RGB_Circle = 20;
	
	public const int T_Dot12864_ST7920 = 21;
	public const int T_Dot12864_ST7565 = 22;
	
	public const int T_zmotor = 23;
	public const int T_16X16_138 = 24;
	
	public const int T_SYN6288 = 25;
	public const int T_UART_Sound = 26;
	
	public const int T_AD_XY = 27;
	
	public const int T_string_list = 28;
	
	public const int T_RGB_LCD = 29;
	static Bitmap rgb_bitmapNormal;
	Graphics rgb_g;
	int RGB_SX;
	int RGB_SY;
	int RGB_EX;
	int RGB_EY;
	int RGB_cx;
	int RGB_cy;
	
	public const int T_MAX7219 = 30;
	SolidBrush T_MAX7219BackBrush;
	
	public const int T_Color = 31;
	SolidBrush T_ColorBrush;
	
	public const int T_K210Screen = 32;
	Bitmap rgb_k210bitmap;
	Graphics rgb_k210g;
	
	public const int T_LAPI = 33;
	public const int T_Timer = 34;
	
	
	public const int T_IO_OUTPUT = 50;
	public const int T_IO_INPUT = 51;
	
	public const int T_IO_LED3 = 52;
	int IO_LED3_PIN_R;
	int IO_LED3_PIN_G;
	int IO_LED3_PIN_B;
	
	public const int T_ValueSensor = 100;
	public const int T_ButtonCircle = 101;
	public const int T_ButtonRec = 102;
	
	//======================================================
	
	public const int T_MB_display = 200;
	
	//======================================================
	
	public const int T_ZK_display = 300;
	public const int T_ZK_rgb = 301;
	
	//======================================================
	
	public const int T_LED22 = 500;
	
	public int Value1; //最小值
	public int Value2; //最大值
	public int Value3;
	
	
	//时钟仿真类
	//System.TimeSpan settime;
	
	SolidBrush BackBrush;
	SolidBrush BackBrush1;
	SolidBrush BackBrush2;
	
	static Pen ServoPen;
	Pen SegPen;
	static Brush[] BeepBrush;
	Brush SegBrush;
	float[] PointList;
	
	static Brush DotCharForeBrush;
	
	static Brush ButtonBrush0;
	static Brush ButtonBrush1;
	static Brush ButtonBrushOn;
	static Brush ButtonBrushOpen;
	
	static Brush SensorBrush0;
	static Brush SensorBrush1;
	
	static Brush ZKBrush;
	
	int[] LastData;
	
	
	int[] SYN6288Buffer;
	int SYN6288Length;
	string SYNMes;
	
	int LastServoAngle;
	
	//直流马达的当前角度
	int MotorAngle;
	
	//字符串类型的缓冲区地址
	int StringAddr;
	bool GBstart;
	int LastChar;
	int S_Number;
	int S_MaxLength;
	
	
	//灯带缓冲地址
	int RGB_ArrayAddr;
	SolidBrush RGBBrush;
	SolidBrush RGBBrush1;
	
	bool MouseOn;
	bool MousePress;
	
	Bitmap bitmap;
	
	static Brush LED22Brush0;
	static Brush LED22Brush1;
	static Brush LED22Brush2;
	
	public Keys BindKey;
	
	const float ST7920_PerW = 2.35f;
	const float ST7920_SW = ST7920_PerW * 8;
	
	static int T_year;
	static int T_month;
	static int T_day;
	static int T_hour;
	static int T_minute;
	static int T_second;
	static int T_week;
	
	static Pen zmotorPen;
	static int TickNumber;
	
	//初始化
	public static void Init()
	{
		zmotorPen = new Pen( Color.FromArgb( 150, 250, 0, 250 ), 7 );
		BeepBrush = new Brush[5];
		BeepBrush[0] = new SolidBrush( Color.FromArgb( 100, 100, 100, 100) );
		BeepBrush[1] = new SolidBrush( Color.FromArgb( 100, 100, 100, 100) );
		BeepBrush[2] = new SolidBrush( Color.FromArgb( 100, 60, 240, 60) );
		BeepBrush[3] = new SolidBrush( Color.FromArgb( 100, 240, 60, 60) );
		BeepBrush[4] = new SolidBrush( Color.FromArgb( 100, 60, 60, 240) );
		
		LED22Brush0 = new SolidBrush( Color.FromArgb( 255, Color.SlateBlue ) );
		LED22Brush1 = new SolidBrush( Color.FromArgb( 180, Color.SlateBlue ) );
		LED22Brush2 = new SolidBrush( Color.FromArgb( 100, Color.SlateBlue ) );
		
		//ZKBrush = new SolidBrush( Color.FromArgb( 100, 64, 62, 79) );
		ZKBrush = new SolidBrush( Color.FromArgb( 100, 50, 56, 70) );
		
		if( SystemData.isBlack ) {
			ServoPen = new Pen( Color.FromArgb(235, 235, 235), 10 );
		}
		else {
			ServoPen = new Pen( Color.SlateBlue, 10 );
		}
		
		ServoPen.StartCap = LineCap.Round;
		ServoPen.EndCap = LineCap.Triangle;
		
		ButtonBrush0 = new SolidBrush( Color.FromArgb( 90, Color.White ) );
		ButtonBrush1 = new SolidBrush( Color.FromArgb( 150, Color.Black ) );
		ButtonBrushOn = new SolidBrush( Color.FromArgb( 10, Color.Black ) );
		ButtonBrushOpen = new SolidBrush( Color.FromArgb( 150, Color.White ) );
		
		SensorBrush0 = new SolidBrush( Color.DarkGray );
		SensorBrush1 = new SolidBrush( Color.Orange );
		
		DotCharForeBrush = new SolidBrush( Color.FromArgb( 10, 20, 10) ); //119 137 92
		
		CPU.Init();
	}
	
	//构造函数
	public SimulateObj( n_HardModule.HardModule o, int id )
	{
		owner = o;
		ID = id;
		
		SimType = 0;
		
		LastData = new int[5];
		
		MousePress = false;
		MouseOn = false;
		
		BindKey = Keys.None;
		PointList = new float[32];
		
		IO_LED3_PIN_R = -1;
		IO_LED3_PIN_G = -1;
		IO_LED3_PIN_B = -1;
		
		//需要改变宽度 所以不作为静态变量
		SegBrush = new SolidBrush( Color.FromArgb(235, 88, 88) );
		SegPen = new Pen( Color.FromArgb(235, 88, 88), 7 );
		SegPen.StartCap = LineCap.Triangle;
		SegPen.EndCap = LineCap.Triangle;
		
		//LED灯类, 需要动态设置颜色
		BackBrush = new SolidBrush( Color.FromArgb( 180, Color.LightCoral ) );
		BackBrush1 = new SolidBrush( Color.FromArgb( 180, Color.LightCoral ) );
		BackBrush2 = new SolidBrush( Color.FromArgb( 180, Color.LightCoral ) );
	}
	
	//tick计数器 - 这里不要太占时间 线程定时器
	public static void Tick()
	{
		TickNumber++;
		if( TickNumber >= 1000 ) {
			TickNumber -= 1000;
			
			T_second++;
			if( T_second >= 60 ) {
				T_second = 0;
				T_minute++;
				if( T_minute >= 60 ) {
					T_minute = 0;
					T_hour++;
					if( T_hour >= 24 ) {
						T_hour = 0;
						T_day++;
						if( T_day >= 31 ) {
							T_day = 1;
							T_month++;
							if( T_month >= 13 ) {
								T_month = 1;
								T_year++;
								if( T_year >= 2099 ) {
									T_year = 2000;
								}
							}
						}
					}
				}
			}
		}
	}
	
	//接收到新的数据
	public void ReceiveData( int Addr, int Data )
	{
		//播放音乐
		if( SimType == T_Beep ) {
			int Vol = Data / 256;
			Data %= 256;
			if( Data != 0 ) {
				if( LastData[Addr] != 0 ) {
					c_MIDI.Music.CloseSound( Addr, LastData[Addr] );
					LastData[Addr] = 0;
				}
				if( Data < 128 ) {
					c_MIDI.Music.PlaySound( Addr, Data, Vol / 2 );
					LastData[Addr] = Data;
				}
			}
			else {
				if( LastData[Addr] != 0 ) {
					c_MIDI.Music.CloseSound( Addr, LastData[Addr] );
					LastData[Addr] = 0;
				}
			}
		}
		//如果是设置时钟
		if( SimType == T_TimeDate ) {
			
			/*
			DateTime dt = System.DateTime.Now + settime;
			int ye = dt.Year;
			int mo = dt.Month;
			int da = dt.Day;
			int ho = dt.Hour;
			int mi = dt.Minute;
			int se = dt.Second;
			int we = (int)dt.DayOfWeek;
			*/
			
			if( Addr == 0 ) {
				T_second = Data;
			}
			if( Addr == 1 ) {
				T_minute = Data;
			}
			if( Addr == 2 ) {
				T_hour = Data;
			}
			if( Value1 == 0 ) {
				if( Addr == 3 ) {
					T_week = Data;
				}
				if( Addr == 4 ) {
					T_day = Data;
				}
				if( Addr == 5 ) {
					T_month = Data;
				}
				if( Addr == 6 ) {
					T_year = Data;
				}
			}
			if( Value1 == 1 ) {
				if( Addr == 3 ) {
					T_day = Data;
				}
				if( Addr == 4 ) {
					T_month = Data;
				}
				if( Addr == 5 ) {
					T_week = Data;
				}
				if( Addr == 6 ) {
					T_year = Data;
				}
			}
			if( Value1 == 2 ) {
				if( Addr == 3 ) {
					T_day = Data;
				}
				if( Addr == 4 ) {
					T_week = Data;
				}
				if( Addr == 5 ) {
					T_month = Data;
				}
				if( Addr == 6 ) {
					T_year = Data;
				}
			}
			
			//dt = new DateTime( ye, mo, da, ho, mi, se );
			//settime = dt.Subtract( System.DateTime.Now );
			//n_Debug.Debug.Message = dt.ToString() + " + " + settime.ToString();
			
		}
		if( SimType == T_Uart ) {
			if( delePortValue != null) {
				delePortValue( Data );
			}
		}
		if( SimType == T_RGB_LCD ) {
			if( Addr == 1 ) {
				RGB_SX = Data;
			}
			if( Addr == 2 ) {
				RGB_SY = Data;
			}
			if( Addr == 3 ) {
				RGB_EX = Data;
			}
			if( Addr == 4 ) {
				RGB_EY = Data;
				
				RGB_cx = RGB_SX;
				RGB_cy = RGB_SY;
			}
			if( Addr == 0 ) {
				
				int bb = Data & 0x1F; Data >>= 5;
				int gg = Data & 0x3F; Data >>= 6;
				int rr = Data & 0x1F;
				Color c = Color.FromArgb( rr * 8, gg * 4, bb * 8 );
				lock( rgb_bitmapNormal ) {
					rgb_bitmapNormal.SetPixel( RGB_cx, RGB_cy, c );
				}
				RGB_cx += 1;
				if( RGB_cx > RGB_EX ) {
					RGB_cx = RGB_SX;
					RGB_cy += 1;
					if( RGB_cy > RGB_EY ) {
						RGB_cy = RGB_SY;
					}
				}
			}
		}
		if( SimType == T_K210Screen ) {
			if( rgb_bitmapNormal != null ) {
				lock( rgb_bitmapNormal ) {
					rgb_k210g.DrawImage( rgb_bitmapNormal, 0, 0 );
				}
			}
		}
		if( SimType == T_SYN6288 ) {
			
			if( SYN6288Length == 0 ) {
				if( Data != 0xFD ) {
					SYN6288Length = 0;
					return;
				}
			}
			SYN6288Buffer[SYN6288Length] = Data;
			SYN6288Length++;
			
			if( SYN6288Length > 3 ) {
				if( SYN6288Length == 3 + SYN6288Buffer[2] ) {
					SYN6288Length = 0;
					
					SYNMes = "";
					for( int i = 0; i < SYN6288Buffer[2] - 3; ++i) {
						
						if( SYN6288Buffer[i + 5] > 127 ) {
							char c = System.Text.Encoding.GetEncoding("GBK").GetChars( new byte[] {(byte)SYN6288Buffer[i+5], (byte)SYN6288Buffer[i+6]} )[0];
							SYNMes += c.ToString();
							i += 1;
						}
						else {
							SYNMes += ((char)SYN6288Buffer[i + 5]).ToString();
						}
					}
				}
			}
		}
		if( SimType == T_UART_Sound ) {
			
			SYN6288Buffer[SYN6288Length] = Data;
			SYN6288Length++;
			
			if( Data == 0 ) {
				SYNMes = "";
				for( int i = 0; i < SYN6288Length - 1; ++i) {
					
					if( SYN6288Buffer[i] > 127 ) {
						char c = System.Text.Encoding.GetEncoding("GBK").GetChars( new byte[] {(byte)SYN6288Buffer[i], (byte)SYN6288Buffer[i+1]} )[0];
						SYNMes += c.ToString();
						i += 1;
					}
					else {
						SYNMes += ((char)SYN6288Buffer[i]).ToString();
					}
				}
				SYN6288Length = 0;
			}
		}
		//判断是否为API接口
		if( SimType == T_LAPI ) {
			//...
		}
		//IO类LED
		if( SimType == T_IO_OUTPUT ) {
			if( Addr == ID ) {
				Value1 = Data;
			}
		}
		//IO类LED3
		if( SimType == T_IO_LED3 ) {
			if( Addr == 0 ) {
				IO_LED3_PIN_R = Data;
			}
			if( Addr == 1 ) {
				IO_LED3_PIN_G = Data;
			}
			if( Addr == 2 ) {
				IO_LED3_PIN_B = Data;
			}
		}
		//IO类输入口
		if( SimType == T_IO_INPUT ) {
			if( Addr == ID ) {
				Value1 = Data;
				CPU.SetIn( Value1, Value3 );
			}
		}
	}
	
	//读取数据
	public void GetData( int Addr )
	{
		if( SimType == 7 ) {
			
			if( Addr == 0 ) {
				owner.DataList[Addr] = T_second;
			}
			if( Addr == 1 ) {
				owner.DataList[Addr] = T_minute;
			}
			if( Addr == 2 ) {
				owner.DataList[Addr] = T_hour;
			}
			if( Value1 == 0 ) {
				if( Addr == 3 ) {
					owner.DataList[Addr] = T_week;
				}
				if( Addr == 4 ) {
					owner.DataList[Addr] = T_day;
				}
				if( Addr == 5 ) {
					owner.DataList[Addr] = T_month;
				}
				if( Addr == 6 ) {
					owner.DataList[Addr] = T_year;
				}
			}
			if( Value1 == 1 ) {
				if( Addr == 3 ) {
					owner.DataList[Addr] = T_day;
				}
				if( Addr == 4 ) {
					owner.DataList[Addr] = T_month;
				}
				if( Addr == 5 ) {
					owner.DataList[Addr] = T_week;
				}
				if( Addr == 6 ) {
					owner.DataList[Addr] = T_year;
				}
			}
			if( Value1 == 2 ) {
				if( Addr == 3 ) {
					owner.DataList[Addr] = T_day;
				}
				if( Addr == 4 ) {
					owner.DataList[Addr] = T_week;
				}
				if( Addr == 5 ) {
					owner.DataList[Addr] = T_month;
				}
				if( Addr == 6 ) {
					owner.DataList[Addr] = T_year;
				}
			}
		}
		/*
		if( SimType == 7 ) {
			
			DateTime dt = new DateTime( ye, mo, da, ho, mi, se );
			dt = dt + (System.DateTime.Now - cTime);
			
			if( Addr == 0 ) {
				owner.DataList[Addr] = dt.Second;
			}
			if( Addr == 1 ) {
				owner.DataList[Addr] = dt.Minute;
			}
			if( Addr == 2 ) {
				owner.DataList[Addr] = dt.Hour;
			}
			if( Value1 == 0 ) {
				if( Addr == 3 ) {
					owner.DataList[Addr] = (int)dt.DayOfWeek;
				}
				if( Addr == 4 ) {
					owner.DataList[Addr] = dt.Day;
				}
				if( Addr == 5 ) {
					owner.DataList[Addr] = dt.Month;
				}
				if( Addr == 6 ) {
					owner.DataList[Addr] = dt.Year;
				}
			}
			if( Value1 == 1 ) {
				if( Addr == 3 ) {
					owner.DataList[Addr] = dt.Day;
				}
				if( Addr == 4 ) {
					owner.DataList[Addr] = dt.Month;
				}
				if( Addr == 5 ) {
					owner.DataList[Addr] = (int)dt.DayOfWeek;
				}
				if( Addr == 6 ) {
					owner.DataList[Addr] = dt.Year;
				}
			}
			if( Value1 == 2 ) {
				if( Addr == 3 ) {
					owner.DataList[Addr] = dt.Day;
				}
				if( Addr == 4 ) {
					owner.DataList[Addr] = (int)dt.DayOfWeek;
				}
				if( Addr == 5 ) {
					owner.DataList[Addr] = dt.Month;
				}
				if( Addr == 6 ) {
					owner.DataList[Addr] = dt.Year;
				}
			}
		}
		*/
		if( SimType == T_Uart ) {
			if( delePortRead != null ) {
				owner.DataList[Addr] = delePortRead();
			}
		}
		
		if( SimType == T_SimLocate ) {
			if( Addr == 0 ) {
				owner.DataList[Addr] = G.SimLocateBox.E;
			}
			if( Addr == 1 ) {
				owner.DataList[Addr] = G.SimLocateBox.W;
			}
		}
		if( SimType == T_LD3320 ) {
			if( Addr == 0 ) {
				owner.DataList[Addr] = n_LD3320Form.LD3320Form.Data;
				n_LD3320Form.LD3320Form.Data = -1;
			}
		}
	}
	
	//仿真开始
	public void Reset()
	{
		c_MIDI.Music.SetTimbre( 2, 23 );
		c_MIDI.Music.SetTimbre( 3, 0 );
		c_MIDI.Music.SetTimbre( 4, 0 );
		
		CPU.Reset();
		
		if( SimType == 7 ) {
			DateTime dt = System.DateTime.Now;
			T_year = dt.Year;
			T_month = dt.Month;
			T_day = dt.Day;
			T_hour = dt.Hour;
			T_minute = dt.Minute;
			T_second = dt.Second;
		}
		if( SimType == T_String ) {
			n_MyObject.MyObject.GroupReplace = true;
			int i = n_VarList.VarList.GetStaticIndex( "#." + owner.Name + ".driver.buffer" );
			n_MyObject.MyObject.GroupReplace = false;
			string addr = n_VarList.VarList.GetAddr( i );
			StringAddr = int.Parse( addr );
			GBstart = false;
			
			//获取数组的长度
			n_MyObject.MyObject.GroupReplace = true;
			i = n_VarList.VarList.GetStaticIndex( "#." + owner.Name + ".driver.MaxLength" );
			n_MyObject.MyObject.GroupReplace = false;
			S_MaxLength = int.Parse( n_VarList.VarList.Get( i ).Value );
		}
		if( SimType == T_string_list ) {
			n_MyObject.MyObject.GroupReplace = true;
			int i = n_VarList.VarList.GetStaticIndex( "#." + owner.Name + ".driver.List" );
			n_MyObject.MyObject.GroupReplace = false;
			string addr = n_VarList.VarList.GetAddr( i );
			StringAddr = int.Parse( addr );
			GBstart = false;
			
			//获取数组的数目和元素长度
			n_MyObject.MyObject.GroupReplace = true;
			i = n_VarList.VarList.GetStaticIndex( "#." + owner.Name + ".driver.Number" );
			n_MyObject.MyObject.GroupReplace = false;
			S_Number = int.Parse( n_VarList.VarList.Get( i ).Value );
			n_MyObject.MyObject.GroupReplace = true;
			i = n_VarList.VarList.GetStaticIndex( "#." + owner.Name + ".driver.MaxLength" );
			n_MyObject.MyObject.GroupReplace = false;
			S_MaxLength = int.Parse( n_VarList.VarList.Get( i ).Value );
		}
		if( SimType == T_RGB_Array || SimType == T_RGB_Circle ) {
			n_MyObject.MyObject.GroupReplace = true;
			int i = n_VarList.VarList.GetStaticIndex( "#." + owner.Name + ".driver.RGBList" );
			n_MyObject.MyObject.GroupReplace = false;
			string addr = n_VarList.VarList.GetAddr( i );
			RGB_ArrayAddr = int.Parse( addr );
			
			RGBBrush = new SolidBrush(Color.WhiteSmoke);
			RGBBrush1 = new SolidBrush(Color.WhiteSmoke);
		}
		if( SimType == T_RGB_LCD ) {
			rgb_bitmapNormal = new Bitmap( Value1, Value2 );
			rgb_g = Graphics.FromImage( rgb_bitmapNormal );
			rgb_g.Clear( Color.Black );
		}
		if( SimType == T_K210Screen ) {
			rgb_k210bitmap = new Bitmap( Value1, Value2 );
			rgb_k210g = Graphics.FromImage( rgb_k210bitmap );
			rgb_k210g.Clear( Color.Black );
		}
		if( SimType == T_SYN6288 || SimType == T_UART_Sound ) {
			SYN6288Buffer = new int[100];
			SYN6288Length = 0;
			SYNMes = "";
		}
		if( SimType == T_MAX7219 ) {
			T_MAX7219BackBrush = new SolidBrush(Color.FromArgb( 100, 0, 0, 0 ) );
		}
		if( SimType == T_Color ) {
			T_ColorBrush = new SolidBrush(Color.Black );
		}
		if( bitmap != null ) {
			Graphics gg = Graphics.FromImage( bitmap );
			gg.Clear( Color.Transparent );
		}
	}
	
	//仿真结束
	public void Close()
	{
		if( SimType == 3 ) {
			for( int Addr = 2; Addr < 4; ++Addr ) {
				if( LastData[Addr] != 0 ) {
					c_MIDI.Music.CloseSound( Addr, LastData[Addr] );
					LastData[Addr] = 0;
				}
			}
		}
	}
	
	//-------------------------------------------------------------------------
	
	//按键按下
	public void MyKeyDown( Keys k )
	{
		if( k == BindKey ) {
			UserMouseDownCore();
		}
	}
	
	//按键松开
	public void MyKeyUp( Keys k )
	{
		if( k == BindKey ) {
			UserMouseUpCore();
		}
	}
	
	//-------------------------------------------------------------------------
	
	//鼠标按下事件
	public bool UserMouseDown( int mX, int mY )
	{
		MouseOn = isMouseOn( mX, mY );
		if( G.CGPanel.MultSelect ) {
			if( MouseOn && MousePress ) {
				UserMouseUpCore();
				return true;
			}
		}
		if( MouseOn ) {
			
			if( G.CGPanel.CKeys != Keys.None ) {
				if( G.CGPanel.CKeys != Keys.ShiftKey ) {
					if( G.CGPanel.CKeys == Keys.Escape ) {
						BindKey = Keys.None;
					}
					else {
						BindKey = G.CGPanel.CKeys;
						GUIcoder.UseBindKey = true;
					}
				}
			}
			MousePress = true;
			UserMouseMove( mX, mY );
			UserMouseDownCore();
		}
		return MouseOn;
	}
	
	//鼠标松开事件
	public void UserMouseUp()
	{
		if( !G.CGPanel.MultSelect ) {
			UserMouseUpCore();
			
			//if( !MouseOn ) {
			//	return;
			//}
		}
	}
	
	void UserMouseDownCore()
	{
		MousePress = true;
		
		if( SimType == T_IO_INPUT ) {
			if( Value3 == 0 ) {
				CPU.SetIn( Value1, 1 );
			}
			else {
				CPU.SetIn( Value1, 0 );
			}
		}
		else if( SimType == T_ButtonCircle || SimType == T_ButtonRec ) {
			if( Value1 >= 100 ) {
				int d = owner.DataList[Value1 - 100];
				if( Value2 / 100 == 1 ) {
					d &= ~(1<<(Value2%100));
				}
				else {
					d |= (1<<(Value2%100));
				}
				owner.DataList[Value1 - 100] = d;
			}
			else {
				owner.DataList[Value1] = Value2;
			}
		}
		else if( SimType == T_Uart ) {
			if( deleOpenUart != null ) {
				deleOpenUart();
			}
		}
		else if( SimType == T_SimLocate ) {
			G.SimLocateBox.Run();
		}
		else if( SimType == T_LD3320 ) {
			if( G.LD3320Box == null ) {
				G.LD3320Box = new n_LD3320Form.LD3320Form();
			}
			G.LD3320Box.Run();
		}
		else {
			//...
		}
	}
	
	void UserMouseUpCore()
	{
		if( !MousePress ) {
			return;
		}
		if( SimType == T_IO_INPUT ) {
			CPU.SetIn( Value1, Value3 );
		}
		else if( SimType == T_ButtonCircle || SimType == T_ButtonRec ) {
			if( Value1 >= 100 ) {
				int d = owner.DataList[Value1 - 100];
				if( Value3 / 100 == 1 ) {
					d &= ~(1<<(Value3%100));
				}
				else {
					d |= (1<<(Value3%100));
				}
				owner.DataList[Value1 - 100] = d;
			}
			else {
				owner.DataList[Value1] = Value3;
			}
		}
		else {
			//...
		}
		MousePress = false;
	}
	
	//鼠标移动事件
	public void UserMouseMove( int mX, int mY )
	{
		MouseOn = isMouseOn( mX, mY );
		if( MousePress ) {
			
			if( SimType == T_ValueSensor ) {
				float v0 = mX - X;
				if( Value3 != 0) {
					//v0 = Width - v0;
				}
				v0 = Value1 + v0 * (Value2 - Value1 + 1 ) / Width;
				if( v0 > Value2 ) {
					v0 = Value2;
				}
				if( v0 < Value1 ) {
					v0 = Value1;
				}
				owner.DataList[0] = (int)v0;
			}
			if( SimType == T_AD_XY ) {
				float v0 = mX - X - 20;
				v0 = v0 * 1024 / (Width-40);
				if( v0 > 1023 ) {
					v0 = 1023;
				}
				if( v0 < 0 ) {
					v0 = 0;
				}
				owner.DataList[0] = (int)v0;
				
				v0 = mY - Y - 20;
				v0 = v0 * 1024 / (Height-40);
				if( v0 > 1023 ) {
					v0 = 1023;
				}
				if( v0 < 0 ) {
					v0 = 0;
				}
				owner.DataList[1] = 1023 - (int)v0;
			}
		}
	}
	
	bool isMouseOn( int ox, int oy )
	{
		if( ox >= X && oy >= Y && ox < X + Width && oy < Y + Height ) {
			return true;
		}
		else {
			return false;
		}
	}
	
	//-------------------------------------------------------------------------
	
	//显示
	public void Draw( Graphics g, int SX, int SY )
	{
		if( owner == null ) {
			g.FillEllipse( BackBrush, SX + X, SY + Y, Width, Height );
			g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
			g.DrawRectangle( Pens.Yellow, SX + X, SY + Y, Width, Height );
		}
		else if( SimType == 0 ) {
			g.FillEllipse( BackBrush, SX + X, SY + Y, Width, Height );
			g.FillEllipse( BackBrush1, SX + X - Width/4, SY + Y - Height/4, Width + Width/2, Height + Height/2 );
			g.FillEllipse( BackBrush1, SX + X - Width/2, SY + Y - Height/2, Width + Width, Height + Height );
			g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
			g.DrawEllipse( Pens.Silver, SX + X - Width/4, SY + Y - Height/4, Width + Width/2, Height + Height/2 );
		}
		else if( SimType == 1 ) {
			//g.DrawRectangle( Pens.LightBlue, SX + X, SY + Y, Width, Height );
			DrawSeg( g, SX, SY );
		}
		else if( SimType == 2 ) {
			//g.DrawRectangle( Pens.LightBlue, SX + X, SY + Y, Width, Height );
			DrawDot( g, SX, SY );
		}
		else if( SimType == 3 ) {
			//g.FillEllipse( BeepBrush, SX + X, SY + Y, Width, Height );
			//g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
			
			for( int i = 0; i < LastData.Length; ++i ) {
				if( LastData[i] == 0 ) {
					continue;
				}
				float w = Width + (LastData[i]-50) * 2;
				float h = Height + (LastData[i]-50) * 2;
				g.FillEllipse( BeepBrush[i], SX + X + Width/2 - w/2, SY + Y + Height/2 - h/2, w, h );
				g.DrawEllipse( Pens.White, SX + X + Width/2 - w/2, SY + Y + Height/2 - h/2, w, h );
			}
		}
		//判断是否是舵机
		else if( SimType == 4 ) {
			
			GraphicsState gs = g.Save();
			n_SG.SG.Rotate( SX + X + Width/2, SY + Y + Height, LastServoAngle );
			g.DrawLine( ServoPen, SX + X + Width/2, SY + Y + Height, SX + X + Width/2, SY + Y );
			g.Restore( gs );
			
			if( LastServoAngle != owner.DataList[0] ) {
				if( LastServoAngle > owner.DataList[0] ) {
					LastServoAngle -= 5;
					if( Math.Abs( LastServoAngle - owner.DataList[0] ) <= 3 ) {
						LastServoAngle = owner.DataList[0];
					}
				}
				else {
					LastServoAngle += 5;
					if( Math.Abs( LastServoAngle - owner.DataList[0] ) <= 3 ) {
						LastServoAngle = owner.DataList[0];
					}
				}
				G.CGPanel.Invalidate();
				G.MyRefresh();
			}
		}
		else if( SimType == 5 ) {
			for( int i = 0; i < 80; ++i ) {
				int Line = i / 20;
				int Column = i % 20;
				char c = ' ';
				if( owner.DataList[i] >= 0 && owner.DataList[i] < 128 ) {
					c = (char)owner.DataList[i];
				}
				if( c != 0 ) {
					DrawChar( g, SX, SY, c, Line, Column );
				}
			}
		}
		else if( SimType == 16 ) {
			for( int i = 0; i < 64; ++i ) {
				int Line = i / 16;
				int Column = i % 16;
				char c = ' ';
				if( owner.DataList[i] >= 0 && owner.DataList[i] < 128 ) {
					c = (char)owner.DataList[i];
					DrawASCChar( g, SX, SY, c, Line, Column );
				}
				else {
					c = System.Text.Encoding.GetEncoding("GBK").GetChars( new byte[] {(byte)owner.DataList[i], (byte)owner.DataList[i+1]} )[0];
					DrawHZChar( g, SX, SY, c, Line, Column );
					i++;
				}
			}
		}
		//直流马达
		else if( SimType == 6 ) {
			if( owner.DataList[0] != 0 ) {
				if( owner.DataList[0] == 1 ) {
					MotorAngle++;
				}
				else {
					MotorAngle--;
				}
				G.CGPanel.Invalidate();
				G.MyRefresh();
			}
			float cx = SX + X + Width/2;
			float cy = SY + Y + Height/2;
			
			float a = (float)(MotorAngle*Math.PI * owner.DataList[1] / 500);
			float r = (Width + Height) / 3;
			float ox = (int)(Width/2 * Math.Sin( a ));
			float oy = (int)(Width/2 * Math.Cos( a ));
			
			if( SystemData.isBlack ) {
				n_SG.SG.MLine.Draw( Color.Yellow, 5, cx + ox, cy + oy, cx - ox, cy - oy );
				n_SG.SG.MCircle.Fill( Color.LightSkyBlue, cx, cy, Width / 10 );
			}
			else {
				n_SG.SG.MLine.Draw( Color.OrangeRed, 5, cx + ox, cy + oy, cx - ox, cy - oy );
				n_SG.SG.MCircle.Fill( Color.DarkOrange, cx, cy, Width / 10 );
			}
		}
		else if( SimType == 7 ) {
			//...
		}
		else if( SimType == 8 ) {
			float cx = SX + X + Width/2;
			float cy = SY + Y + Height/2;
			float a = (float)(owner.DataList[0]*Math.PI/180);
			float r = (Width + Height) / 3;
			float ox = (int)(Width/2 * Math.Sin( a ));
			float oy = (int)(Width/2 * Math.Cos( a ));
			n_SG.SG.MLine.Draw( Color.OrangeRed, 5, cx + ox, cy + oy, cx - ox, cy - oy );
			n_SG.SG.MCircle.Fill( Color.Orange, cx, cy, Width / 10 );
		}
		else if( SimType == T_Uart ) {
			float cx = SX + X;
			float cy = SY + Y;
			n_SG.SG.MRectangle.Fill( Color.Orange, cx, cy, Width, Height );
		}
		else if( SimType == T_DataDisplay ) {
			float cx = SX + X;
			float cy = SY + Y;
			string DanWei = "";
			if( Value1 == 1 ) {
				DanWei = "Hz";
			}
			if( Value1 == 2 ) {
				DanWei = "%";
			}
			if( SystemData.isBlack ) {
				g.DrawString( owner.DataList[0] + DanWei, n_GUIset.GUIset.SimFont, Brushes.Yellow,  SX + X , SY + Y - 3 );
			}
			else {
				g.DrawString( owner.DataList[0] + DanWei, n_GUIset.GUIset.SimFont, Brushes.Black,  SX + X , SY + Y - 3 );
			}
		}
		else if( SimType == T_SimLocate ) {
			if( MouseOn ) {
				g.FillRectangle( Brushes.Yellow, SX + X, SY + Y, Width, Height );
				g.DrawRectangle( Pens.Black, SX + X, SY + Y, Width, Height );
			}
			else {
				g.FillRectangle( Brushes.YellowGreen, SX + X, SY + Y, Width, Height );
				g.DrawRectangle( Pens.Black, SX + X, SY + Y, Width, Height );
			}
		}
		else if( SimType == T_LD3320 ) {
			if( MouseOn ) {
				g.FillEllipse( Brushes.MediumOrchid, SX + X, SY + Y, Width, Height );
				g.DrawEllipse( Pens.Black, SX + X, SY + Y, Width, Height );
			}
			else {
				g.FillEllipse( Brushes.MediumPurple, SX + X, SY + Y, Width, Height );
				g.DrawEllipse( Pens.Black, SX + X, SY + Y, Width, Height );
			}
		}
		else if( SimType == T_zmotor ) {
			int v = owner.DataList[0]/5;
			
			if( owner.DataList[1] != 0 ) {
				g.DrawString( owner.DataList[0].ToString(), n_GUIset.GUIset.SimFont, Brushes.WhiteSmoke, SX + X + 3, SY + Y + 6 );
				g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
				g.DrawEllipse( zmotorPen, SX + X - v, SY + Y - v, Width + v*2, Height + v*2 );
				g.DrawEllipse( Pens.White, SX + X - v, SY + Y - v, Width + v*2, Height + v*2 );
			}
		}
		else if( SimType == T_String ) {
			
			string temp = "";
			int i = 0;
			while( true ) {
				byte b = n_UserModule.UserModule.BASE[ StringAddr + i ];
				if( b == 0 ) {
					break;
				}
				if( i >= S_MaxLength ) {
					break;
				}
				int Data = b;
				if( GBstart ) {
					GBstart = false;
					char c = System.Text.Encoding.GetEncoding("GBK").GetChars( new byte[] {(byte)LastChar, (byte)Data} )[0];
					temp += c;
				}
				else {
					if( Data > 127 ) {
						GBstart = true;
						LastChar = Data;
						i++;
						continue;
					}
					temp += (char)Data;
				}
				i++;
			}
			if( i >= S_MaxLength ) {
				g.DrawString( "长度溢出:" + i + " (<" + S_MaxLength + ")", n_GUIset.GUIset.ModuleNameFont, Brushes.Red,  SX + X + owner.Width + 10, SY + Y - 25 );
			}
			else {
				g.DrawString( "当前长度:" + i + " (<" + S_MaxLength + ")", n_GUIset.GUIset.ModuleNameFont, Brushes.CornflowerBlue,  SX + X + owner.Width + 10, SY + Y - 25 );
			}
			
			g.DrawString( temp, n_GUIset.GUIset.ModuleNameFont, Brushes.SlateGray,  SX + X, SY + Y );
		}
		else if( SimType == T_string_list ) {
			
			for( int n = 0; n < S_Number; n++ ) {
				string temp = "";
				int i = 0;
				while( true ) {
					byte b = n_UserModule.UserModule.BASE[ StringAddr + n*S_MaxLength + i ];
					if( b == 0 ) {
						break;
					}
					if( i >= S_MaxLength ) {
						break;
					}
					int Data = b;
					if( GBstart ) {
						GBstart = false;
						char c = System.Text.Encoding.GetEncoding("GBK").GetChars( new byte[] {(byte)LastChar, (byte)Data} )[0];
						temp += c;
					}
					else {
						if( Data > 127 ) {
							GBstart = true;
							LastChar = Data;
							i++;
							continue;
						}
						temp += (char)Data;
					}
					i++;
				}
				if( i >= S_MaxLength ) {
					g.DrawString( n + " 长度溢出:" + i + " (<" + S_MaxLength + ")", n_GUIset.GUIset.ModuleNameFont, Brushes.Red,  SX + X, SY + Y + n*25 );
				}
				else {
					g.DrawString( n + " 当前长度:" + i + " (<" + S_MaxLength + ")", n_GUIset.GUIset.ModuleNameFont, Brushes.CornflowerBlue,  SX + X, SY + Y + n*25 );
				}
				
				g.DrawString( temp, n_GUIset.GUIset.ModuleNameFont, Brushes.SlateGray,  SX + X + 120, SY + Y + n*25 );
			}
		}
		else if( SimType == T_RGB_LCD ) {
			lock( rgb_bitmapNormal ) {
				GraphicsState gs00 = g.Save();
				g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
				
				if( n_HardModule.HardModule.ShowBigImage || owner.isMouseOnBase ) {
					g.DrawImage( rgb_bitmapNormal, SX + X + (Width-rgb_bitmapNormal.Width)/2,
					             SY + Y + (Height-rgb_bitmapNormal.Height)/2, rgb_bitmapNormal.Width, rgb_bitmapNormal.Height );
					
					//if( !n_HardModule.HardModule.ShowBigImage ) {
					float ssx = SX + X + (Width-rgb_bitmapNormal.Width)/2;
					float xxy = SY + Y + Height/2 + rgb_bitmapNormal.Height/2;
					string mes = "空格键可切换始终显示大图";
					SizeF s = g.MeasureString( mes, n_GUIset.GUIset.ModuleNameFont );
					g.FillRectangle( Brushes.WhiteSmoke, ssx, xxy, s.Width, s.Height );
					g.DrawRectangle( Pens.OrangeRed, ssx, xxy, s.Width, s.Height );
					g.DrawString( mes, n_GUIset.GUIset.ModuleNameFont, Brushes.OrangeRed, ssx, xxy );
					//}
				}
				else {
					g.DrawImage( rgb_bitmapNormal, SX + X, SY + Y, Width, Height );
				}
				
				g.Restore( gs00 );
			}
			
		}
		else if( SimType == T_K210Screen ) {
			lock( rgb_k210bitmap ) {
				GraphicsState gs00 = g.Save();
				g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
				
				if( n_HardModule.HardModule.ShowBigImage || owner.isMouseOnBase ) {
					g.DrawImage( rgb_k210bitmap, SX + X + (Width-rgb_k210bitmap.Width)/2,
					             SY + Y + (Height-rgb_k210bitmap.Height)/2, rgb_k210bitmap.Width, rgb_k210bitmap.Height );
					
					//if( !n_HardModule.HardModule.ShowBigImage ) {
					float ssx = SX + X + (Width-rgb_k210bitmap.Width)/2;
					float xxy = SY + Y + Height/2 + rgb_k210bitmap.Height/2;
					string mes = "空格键可切换始终显示大图";
					SizeF s = g.MeasureString( mes, n_GUIset.GUIset.ModuleNameFont );
					g.FillRectangle( Brushes.WhiteSmoke, ssx, xxy, s.Width, s.Height );
					g.DrawRectangle( Pens.OrangeRed, ssx, xxy, s.Width, s.Height );
					g.DrawString( mes, n_GUIset.GUIset.ModuleNameFont, Brushes.OrangeRed, ssx, xxy );
					//}
				}
				else {
					g.DrawImage( rgb_k210bitmap, SX + X, SY + Y, Width, Height );
				}
				g.Restore( gs00 );
			}
		}
		else if( SimType == T_SYN6288 || SimType == T_UART_Sound ) {
			g.DrawString( "朗读内容: " + SYNMes, n_GUIset.GUIset.Font14, Brushes.OrangeRed,  SX + X, SY + Y - 70 );
		}
		//判断是否为灯带
		else if( SimType == T_RGB_Array ) {
			
			int number = owner.DataList[0];
			
			//g.FillRectangle( Brushes.SlateGray, SX + X, SY + Y, number * Height + 4, Height );
			g.DrawRectangle( Pens.SlateGray, SX + X, SY + Y, number * Height + 4, Height );
			
			for( int i = 0; i < number; ++i ) {
				
				byte R = n_UserModule.UserModule.BASE[ RGB_ArrayAddr + i * 3 ];
				byte G = n_UserModule.UserModule.BASE[ RGB_ArrayAddr + i * 3 + 1 ];
				byte B = n_UserModule.UserModule.BASE[ RGB_ArrayAddr + i * 3 + 2 ];
				RGBBrush.Color = Color.FromArgb( R, G, B );
				RGBBrush1.Color = Color.FromArgb( 80, R, G, B );
				
				g.FillEllipse( RGBBrush, SX + X + i * Height + 4, SY + Y + 4, Height - 8, Height - 8 );
				g.DrawEllipse( Pens.SlateGray, SX + X + i * Height + 4, SY + Y + 4, Height - 8, Height - 8 );
				g.FillEllipse( RGBBrush1, SX + X + i * Height - 2, SY + Y - 2, Height + 4, Height + 4 );
			}
		}
		//判断是否为灯环
		else if( SimType == T_RGB_Circle ) {
			
			int number = owner.DataList[0];
			
			//g.FillRectangle( Brushes.SlateGray, SX + X, SY + Y, number * Height + 4, Height );
			//g.DrawRectangle( Pens.SlateGray, SX + X, SY + Y, number * Height + 4, Height );
			int LEDWidth = 21;
			float r = Width / 2 - LEDWidth / 2 - 5;
			for( int i = 0; i < number; ++i ) {
				
				float a = (float)(i * 2 * Math.PI / number);
				if( Value1 != 0 ) {
					a += (float)( Value1 * Math.PI / 360 );
					a = -a;
				}
				if( Value2 == 0 ) {
					a = -a;
				}
				
				float x = (float)(r * -Math.Sin( a ));
				float y = (float)(r * Math.Cos( a ));
				x = SX + MidX + x - 0.5f;
				y = SY + Y + Width/2 + y;
				
				byte R = n_UserModule.UserModule.BASE[ RGB_ArrayAddr + i * 3 ];
				byte G = n_UserModule.UserModule.BASE[ RGB_ArrayAddr + i * 3 + 1 ];
				byte B = n_UserModule.UserModule.BASE[ RGB_ArrayAddr + i * 3 + 2 ];
				RGBBrush.Color = Color.FromArgb( R, G, B );
				RGBBrush1.Color = Color.FromArgb( 120, R, G, B );
				
				g.FillEllipse( RGBBrush, x - LEDWidth/2, y - LEDWidth/2, LEDWidth, LEDWidth );
				g.DrawEllipse( Pens.Gray, x - LEDWidth/2, y - LEDWidth/2, LEDWidth, LEDWidth );
				g.FillEllipse( RGBBrush1, x - LEDWidth/2 - 6, y - LEDWidth/2 - 6, LEDWidth + 12, LEDWidth + 12 );
			}
		}
		//多路数值
		else if( SimType == T_MultData ) {
			for( int i = 0; i < 10; ++i ) {
				int dd = owner.DataList[i];
				if( dd == 0 ) {
					continue;
				}
				int dx = dd;
				if( dx >= 7000 ) dx = 7000;
				g.FillRectangle( Brushes.WhiteSmoke, SX + X - 1, SY + Y + 5 + i * 20, 71, 17 );
				g.FillRectangle( SensorBrush1, SX + X, SY + Y + 6 + i * 20, dx / 100, 15 );
				if( SystemData.isBlack ) {
					g.DrawString( owner.DataList[i].ToString(), n_GUIset.GUIset.SimFont, Brushes.WhiteSmoke,  SX + X , SY + Y + i * 20 );
				}
				else {
					g.DrawString( owner.DataList[i].ToString(), n_GUIset.GUIset.SimFont, Brushes.DarkSlateGray,  SX + X , SY + Y + i * 20 );
				}
			}
		}
		//数值型传感器
		else if( SimType == T_ValueSensor ) {
			
			Y = -owner.Height/2 - 60;
			
			float xx = (float)(owner.DataList[0] - Value1) / ( Value2 - Value1 + 1 );
			if( MouseOn ) {
				g.FillRectangle( Brushes.Gainsboro, SX + X - 2, SY + Y - 2, Width + 4, Height + 4 );
				g.FillRectangle( SensorBrush1, SX + X, SY + Y, xx * Width, Height );
			}
			else {
				g.FillRectangle( SensorBrush0, SX + X - 2, SY + Y - 2, Width + 4, Height + 4 );
				g.FillRectangle( Brushes.DarkGoldenrod, SX + X, SY + Y, xx * Width, Height );
			}
			g.DrawString( (int)(100 * xx) + "%", n_GUIset.GUIset.SimFont, Brushes.Black,  SX + X , SY + Y - 3 );
			
			//容易引起误解 不显示原始值
			//g.DrawString( "(" + owner.DataList[0].ToString() + ")", n_GUIset.GUIset.SimFont, Brushes.SlateGray,  SX + X + Width/2, SY + Y - 3 ); // -30在上边
		}
		else if( SimType == T_AD_XY ) {
			float xx = (owner.DataList[0]) * (Width-40) / 1024;
			float yy = (1023-owner.DataList[1]) * (Height-40) / 1024;
			g.FillEllipse( Brushes.YellowGreen, SX + X + 20 + xx - 20, SY + Y + 20 + yy - 20, 40, 40 );
			g.FillEllipse( Brushes.OrangeRed, SX + X + 20 + xx - 18, SY + Y + 20 + yy - 18, 36, 36 );
		}
		else if( SimType == T_ButtonCircle ) {
			if( MousePress ) {
				g.FillEllipse( ButtonBrush1, SX + X, SY + Y, Width, Height );
				g.DrawEllipse( Pens.Yellow, SX + X, SY + Y, Width, Height );
			}
			else {
				if( MouseOn ) {
					g.FillEllipse( ButtonBrushOn, SX + X, SY + Y, Width, Height );
					g.DrawEllipse( Pens.Goldenrod, SX + X, SY + Y, Width, Height );
				}
				else {
					g.FillEllipse( ButtonBrush0, SX + X, SY + Y, Width, Height );
				}
			}
			if( MouseOn ) {
				//g.DrawEllipse( Pens.Orange, SX + X, SY + Y, Width, Height );
			}
			else {
				g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
			}
			
			//这里好像是用来显示白灯+按键的仿真 友高的模块
			if( owner.DataList[1024] != 0 ) {
				g.FillEllipse( ButtonBrushOpen, SX + X - Width/2, SY + Y - Height/2, Width*2, Height*2 );
				g.DrawEllipse( Pens.Silver, SX + X - Width/2, SY + Y - Height/2, Width*2, Height*2 );
			}
			
			if( BindKey != Keys.None ) {
				n_SG.SG.MString.DrawAtCenter( BindKey.ToString(), Color.Black, 15, SX + X + Width/2, SY + Y + Height/2 );
			}
		}
		else if( SimType == T_ButtonRec ) {
			//if( MousePress || owner.DataList[Value1] == Value2 ) {
			if( MousePress ) {
				g.FillRectangle( ButtonBrush1, SX + X, SY + Y, Width, Height );
			}
			else {
				if( MouseOn ) {
					g.FillRectangle( ButtonBrushOn, SX + X, SY + Y, Width, Height );
				}
				else {
					g.FillRectangle( ButtonBrush0, SX + X, SY + Y, Width, Height );
				}
			}
			if( MouseOn ) {
				//g.DrawRectangle( Pens.Orange, SX + X, SY + Y, Width, Height );
			}
			else {
				g.DrawRectangle( Pens.White, SX + X, SY + Y, Width, Height );
			}
			
			if( BindKey != Keys.None ) {
				n_SG.SG.MString.DrawAtCenter( BindKey.ToString(), Color.Black, 15, SX + X + Width/2, SY + Y + Height/2 );
			}
		}
		else if( SimType == T_Dot12864 ) {
			
			if( owner.DataListChanged ) {
				owner.DataListChanged = false;
				Graphics gg = Graphics.FromImage( bitmap );
				gg.Clear( Color.Black );
				for( int i = 0; i < 8; ++i ) {
					for( int j = 0; j < 128; ++j ) {
					
						byte b = (byte)owner.DataList[i*128+j];
						
						int x = j;
						int y = i * 8;
						Brush b0;
						Brush b1;
						if( j % 2 == 0 ) {
							//b0 = Brushes.Lavender;
							//b1 = Brushes.Azure;
							b0 = Brushes.LemonChiffon;
							b1 = Brushes.PaleTurquoise;
						}
						else {
							//b0 = Brushes.Azure;
							//b1 = Brushes.Lavender;
							b0 = Brushes.PaleTurquoise;
							b1 = Brushes.LemonChiffon;
						}
						if( (b & 0x01) != 0 ) gg.FillRectangle( b0, x, y + 0, 1, 1 );
						if( (b & 0x02) != 0 ) gg.FillRectangle( b1, x, y + 1, 1, 1 );
						if( (b & 0x04) != 0 ) gg.FillRectangle( b0, x, y + 2, 1, 1 );
						if( (b & 0x08) != 0 ) gg.FillRectangle( b1, x, y + 3, 1, 1 );
						if( (b & 0x10) != 0 ) gg.FillRectangle( b0, x, y + 4, 1, 1 );
						if( (b & 0x20) != 0 ) gg.FillRectangle( b1, x, y + 5, 1, 1 );
						if( (b & 0x40) != 0 ) gg.FillRectangle( b0, x, y + 6, 1, 1 );
						if( (b & 0x80) != 0 ) gg.FillRectangle( b1, x, y + 7, 1, 1 );
					}
				}
			}
			GraphicsState gs = g.Save();
			g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
			//g.DrawImage( bitmap, SX - 64, SY - 41, Width, Height );
			
			if( n_HardModule.HardModule.ShowBigImage || owner.isMouseOnBase) {
				g.DrawImage( bitmap, SX + X + (Width-bitmap.Width*2)/2,
				            SY + Y + (Height-bitmap.Height*2)/2, bitmap.Width*2, bitmap.Height*2 );
				
				//if( !n_HardModule.HardModule.ShowBigImage ) {
				float ssx = SX + X + (Width-bitmap.Width*2)/2;
				float xxy = SY + Y + Height/2 + bitmap.Height*2/2;
				string mes = "空格键可切换始终显示大图";
				SizeF s = g.MeasureString( mes, n_GUIset.GUIset.ModuleNameFont );
				g.FillRectangle( Brushes.WhiteSmoke, ssx, xxy, s.Width, s.Height );
				g.DrawRectangle( Pens.OrangeRed, ssx, xxy, s.Width, s.Height );
				g.DrawString( mes, n_GUIset.GUIset.ModuleNameFont, Brushes.OrangeRed, ssx, xxy );
				//}
			}
			else {
				g.DrawImage( bitmap, SX + X, SY + Y, Width, Height );
			}
			
			g.Restore( gs );
		}
		else if( SimType == T_Dot12864_ST7920 ) {
			
			//g.DrawRectangle( Pens.White, SX + X, SY + Y, Width, Height );
			
			GraphicsState gs = g.Save();
			g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
			
			float PerW = Width / 128;
			float PerH = Height / 64;
			float DPerW = PerW * 0.8f;
			float DPerH = PerH * 0.8f;
			
			float w = DPerW;
			float h = DPerH;
			for( int i = 0; i < 16; ++i ) {
				for( int j = 0; j < 64; ++j ) {
					
					byte b = (byte)owner.DataList[i*64+j];
					
					float x = SX + X + (16 - i) * PerW * 8 - PerW;
					float y = SY + Y + j * PerH;
					
					Brush b1 = Brushes.DarkBlue;
					Brush b0 = Brushes.LemonChiffon;
					
					if( (b & 0x01) != 0 ) g.FillRectangle( b0, x - PerW*0, y, w, h ); else g.FillRectangle( b1, x - PerW*0, y, w, h ); 
					if( (b & 0x02) != 0 ) g.FillRectangle( b0, x - PerW*1, y, w, h ); else g.FillRectangle( b1, x - PerW*1, y, w, h );
					if( (b & 0x04) != 0 ) g.FillRectangle( b0, x - PerW*2, y, w, h ); else g.FillRectangle( b1, x - PerW*2, y, w, h );
					if( (b & 0x08) != 0 ) g.FillRectangle( b0, x - PerW*3, y, w, h ); else g.FillRectangle( b1, x - PerW*3, y, w, h );
					if( (b & 0x10) != 0 ) g.FillRectangle( b0, x - PerW*4, y, w, h ); else g.FillRectangle( b1, x - PerW*4, y, w, h );
					if( (b & 0x20) != 0 ) g.FillRectangle( b0, x - PerW*5, y, w, h ); else g.FillRectangle( b1, x - PerW*5, y, w, h );
					if( (b & 0x40) != 0 ) g.FillRectangle( b0, x - PerW*6, y, w, h ); else g.FillRectangle( b1, x - PerW*6, y, w, h );
					if( (b & 0x80) != 0 ) g.FillRectangle( b0, x - PerW*7, y, w, h ); else g.FillRectangle( b1, x - PerW*7, y, w, h );
				}
			}
			g.Restore( gs );
		}
		else if( SimType == T_Dot12864_ST7565 ) {
			
			//g.DrawRectangle( Pens.White, SX + X, SY + Y, Width, Height );
			
			GraphicsState gs = g.Save();
			g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
			
			float PerW = Width / 128;
			float PerH = Height / 64;
			float DPerW = PerW * 0.8f;
			float DPerH = PerH * 0.8f;
			
			float w = DPerW;
			float h = DPerH;
			for( int i = 0; i < 8; ++i ) {
				for( int j = 0; j < 128; ++j ) {
					
					byte b = (byte)owner.DataList[i*128+j];
					
					float x = SX + X + j * PerW - PerW;
					float y = SY + Y + i * PerH * 8;
					
					Brush b1 = Brushes.Silver;
					Brush b0 = Brushes.Black;
					
					if( (b & 0x01) != 0 ) g.FillRectangle( b0, x, y + PerW*0, w, h ); else g.FillRectangle( b1, x, y + PerW*0, w, h ); 
					if( (b & 0x02) != 0 ) g.FillRectangle( b0, x, y + PerW*1, w, h ); else g.FillRectangle( b1, x, y + PerW*1, w, h );
					if( (b & 0x04) != 0 ) g.FillRectangle( b0, x, y + PerW*2, w, h ); else g.FillRectangle( b1, x, y + PerW*2, w, h );
					if( (b & 0x08) != 0 ) g.FillRectangle( b0, x, y + PerW*3, w, h ); else g.FillRectangle( b1, x, y + PerW*3, w, h );
					if( (b & 0x10) != 0 ) g.FillRectangle( b0, x, y + PerW*4, w, h ); else g.FillRectangle( b1, x, y + PerW*4, w, h );
					if( (b & 0x20) != 0 ) g.FillRectangle( b0, x, y + PerW*5, w, h ); else g.FillRectangle( b1, x, y + PerW*5, w, h );
					if( (b & 0x40) != 0 ) g.FillRectangle( b0, x, y + PerW*6, w, h ); else g.FillRectangle( b1, x, y + PerW*6, w, h );
					if( (b & 0x80) != 0 ) g.FillRectangle( b0, x, y + PerW*7, w, h ); else g.FillRectangle( b1, x, y + PerW*7, w, h );
				}
			}
			g.Restore( gs );
		}
		//判断是否arduino兼容库仿真
		else if( SimType == T_Arduino ) {
			float ww = ((float)Width - 6) / 13;
			for( int i = 0; i < 14; ++i ) {
				if( owner.DataList[13 - i] == 0 ) {
					g.FillRectangle( Brushes.Blue, SX + X + (int)(i * ww), SY + Y, 6, 6 );
				}
				else {
					g.FillRectangle( Brushes.Red, SX + X + (int)(i * ww), SY + Y, 6, 6 );
				}
			}
			for( int i = 0; i < 6; ++i ) {
				if( owner.DataList[14 + i] == 0 ) {
					g.FillEllipse( Brushes.Blue, SX + X + (int)((i + 8) * ww), SY + Y + Height - 6, 6, 6 );
				}
				else {
					g.FillEllipse( Brushes.Red, SX + X + (int)((i + 8) * ww), SY + Y + Height - 6, 6, 6 );
				}
			}
		}
		
		//==================================================================
		else if( SimType == T_IO_OUTPUT ) {
			int d = CPU.GetOut( Value1 );
			if( d != 0 && Value3 != 0 || d == 0 && Value3 == 0 ) {
				
				SetColor( Value2 );
				
				g.FillEllipse( BackBrush, SX + X, SY + Y, Width, Height );
				g.FillEllipse( BackBrush1, SX + X - Width/4, SY + Y - Height/4, Width + Width/2, Height + Height/2 );
				g.FillEllipse( BackBrush2, SX + X - Width/2, SY + Y - Height/2, Width + Width, Height + Height );
				g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
				//g.DrawEllipse( Pens.Silver, SX + X - Width/4, SY + Y - Height/4, Width + Width/2, Height + Height/2 );
			}
		}
		else if( SimType == T_IO_LED3 ) {
			int c = 0;
			int rr = CPU.GetOut( IO_LED3_PIN_R );
			if( rr != 0 && Value3 != 0 || rr == 0 && Value3 == 0 ) {
				c += 0xFF0000;
			}
			int gg = CPU.GetOut( IO_LED3_PIN_G );
			if( gg != 0 && Value3 != 0 || gg == 0 && Value3 == 0 ) {
				c += 0xFF00;
			}
			int bb = CPU.GetOut( IO_LED3_PIN_B );
			if( bb != 0 && Value3 != 0 || bb == 0 && Value3 == 0 ) {
				c += 0xFF;
			}
			SetColor( c );
			g.FillEllipse( BackBrush, SX + X, SY + Y, Width, Height );
			g.FillEllipse( BackBrush1, SX + X - Width/4, SY + Y - Height/4, Width + Width/2, Height + Height/2 );
			g.FillEllipse( BackBrush2, SX + X - Width/2, SY + Y - Height/2, Width + Width, Height + Height );
			g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
			//g.DrawEllipse( Pens.Silver, SX + X - Width/4, SY + Y - Height/4, Width + Width/2, Height + Height/2 );
		}
		else if( SimType == T_IO_INPUT ) {
			
			if( MousePress ) {
				g.FillEllipse( ButtonBrush1, SX + X, SY + Y, Width, Height );
				g.DrawEllipse( Pens.Yellow, SX + X, SY + Y, Width, Height );
			}
			else {
				if( MouseOn ) {
					g.FillEllipse( ButtonBrushOn, SX + X, SY + Y, Width, Height );
					g.DrawEllipse( Pens.Goldenrod, SX + X, SY + Y, Width, Height );
				}
				else {
					g.FillEllipse( ButtonBrush0, SX + X, SY + Y, Width, Height );
				}
			}
			if( MouseOn ) {
				//g.DrawEllipse( Pens.Orange, SX + X, SY + Y, Width, Height );
			}
			else {
				g.DrawEllipse( Pens.White, SX + X, SY + Y, Width, Height );
			}
			if( BindKey != Keys.None ) {
				n_SG.SG.MString.DrawAtCenter( BindKey.ToString(), Color.Black, 15, SX + X + Width/2, SY + Y + Height/2 );
			}
		}
		//==================================================================
		else if( SimType == T_16X32 ) {
			
			if( owner.DataListChanged ) {
				owner.DataListChanged = false;
				Graphics gg = Graphics.FromImage( bitmap );
				gg.Clear( Color.Transparent );
				
				for( int i = 0; i < 4; ++i ) {
					for( int j = 0; j < 16; ++j ) {
					
						byte b = (byte)owner.DataList[i*16+j];
						
						int x = j;
						int y = i * 8;
						Brush b0;
						Brush b1;
						if( j % 2 == 0 ) {
							//b0 = Brushes.Lavender;
							//b1 = Brushes.Azure;
							b0 = Brushes.LemonChiffon;
							b1 = Brushes.PaleTurquoise;
						}
						else {
							//b0 = Brushes.Azure;
							//b1 = Brushes.Lavender;
							b0 = Brushes.PaleTurquoise;
							b1 = Brushes.LemonChiffon;
						}
						
						if( (b & 0x01) != 0 ) gg.FillRectangle( b0, x, y + 0, 1, 1 );
						if( (b & 0x02) != 0 ) gg.FillRectangle( b1, x, y + 1, 1, 1 );
						if( (b & 0x04) != 0 ) gg.FillRectangle( b0, x, y + 2, 1, 1 );
						if( (b & 0x08) != 0 ) gg.FillRectangle( b1, x, y + 3, 1, 1 );
						if( (b & 0x10) != 0 ) gg.FillRectangle( b0, x, y + 4, 1, 1 );
						if( (b & 0x20) != 0 ) gg.FillRectangle( b1, x, y + 5, 1, 1 );
						if( (b & 0x40) != 0 ) gg.FillRectangle( b0, x, y + 6, 1, 1 );
						if( (b & 0x80) != 0 ) gg.FillRectangle( b1, x, y + 7, 1, 1 );
					}
				}
			}
			GraphicsState gs = g.Save();
			g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
			g.DrawImage( bitmap, SX + X, SY + Y, Width, Height );
			g.Restore( gs );
		}
		else if( SimType == T_16X16_138 ) {
			
			for( int i = 0; i < 2; ++i ) {
				for( int j = 0; j < 16; ++j ) {
					
					byte b = (byte)owner.DataList[i*16+j];
					
					int w = 12;
					float pw = 16.9f;
					float pwx = 16.83f;
					float x = SX + X + Width - 15.33f - i * 8 * pwx;
					float y = SY + Y + 3 + j * pw;
					
					Brush b0 = Brushes.Coral;
					if( (b & 0x01) != 0 ) g.FillEllipse( b0, x - 0 * pw, y, w, w );
					if( (b & 0x02) != 0 ) g.FillEllipse( b0, x - 1 * pw, y, w, w );
					if( (b & 0x04) != 0 ) g.FillEllipse( b0, x - 2 * pw, y, w, w );
					if( (b & 0x08) != 0 ) g.FillEllipse( b0, x - 3 * pw, y, w, w );
					if( (b & 0x10) != 0 ) g.FillEllipse( b0, x - 4 * pw, y, w, w );
					if( (b & 0x20) != 0 ) g.FillEllipse( b0, x - 5 * pw, y, w, w );
					if( (b & 0x40) != 0 ) g.FillEllipse( b0, x - 6 * pw, y, w, w );
					if( (b & 0x80) != 0 ) g.FillEllipse( b0, x - 7 * pw, y, w, w );
				}
			}
		}
		else if( SimType == T_MAX7219 ) {
			DrawDotMax7219( g, SX, SY );
		}
		else if( SimType == T_Color ) {
			DrawColor( g, SX, SY );
		}
		//判断是否为API接口
		else if( SimType == T_LAPI ) {
			//...
		}
		//多路数值
		else if( SimType == T_Timer ) {
			
			int dd = owner.DataList[0];
			int max = owner.DataList[1];
			if( dd <= 0 || max <= 0 ) {
				return;
			}
			g.DrawRectangle( Pens.SlateGray, SX + X - 1, SY + Y, 100, 24 );
			g.FillRectangle( Brushes.DarkGray, SX + X + 1, SY + Y + 2, 100 * dd / max - 1, 20 );
			
			g.DrawString( dd + " 毫秒", n_GUIset.GUIset.ModuleNameFont, Brushes.Black,  SX + X , SY + Y + 3 );
			g.DrawString( max + " 毫秒", n_GUIset.GUIset.ModuleNameFont, Brushes.SlateGray,  SX + X , SY + Y + Height + 5 );
		}
		
		//==========================================================================
		
		//判断是否为microbit仿真控件
		else if( SimType == T_MB_display ) {
			MB_display( g, SX, SY );
		}
		//判断是否为掌控板仿真控件
		else if( SimType == T_ZK_display ) {
			ZK_display( g, SX, SY );
		}
		//判断是否为掌控板仿真控件
		else if( SimType == T_ZK_rgb ) {
			ZK_rgb( g, SX, SY );
		}
		//判断是否为定制类灯带
		else if( SimType == T_LED22 ) {
			float ww = ((float)Width) / 21;
			for( int i = 0; i < 22; ++i ) {
				if( owner.DataList[i] != 0 ) {
					float cx = SX + X + (int)(i * ww) + 4.5f;
					float cy = SY + Y + Height - 4.5f;
					float wh = (float)owner.DataList[i] / 10;
					g.FillEllipse( LED22Brush0, cx - wh / 2, cy - wh / 2, wh, wh ); wh *= 1.5f;
					g.FillEllipse( LED22Brush1, cx - wh / 2, cy - wh / 2, wh, wh ); wh *= 1.3f;
					g.FillEllipse( LED22Brush2, cx - wh / 2, cy - wh / 2, wh, wh );
				}
			}
		}
		else {
			g.FillEllipse( Brushes.Red, SX + X, SY + Y, Width, Height );
		}
	}
	
	//===================================================================================
	
	//显示micro:bit的display控件
	void MB_display( Graphics g, int SX, int SY )
	{
		for( int x = 0; x < 5; ++x ) {
			for( int y = 0; y < 5; ++y ) {
				
				int d = owner.DataList[ x*5 + y ];
				
				float w = Width/10f;
				float h = Height/6f;
				
				float bx = SX + X + x*Width/4.45f;
				float by = SY + Y + y*Height/4.9f;
				
				if( d != 0 ) {
					
					g.FillEllipse( Brushes.Yellow, bx, by, w, h );
					g.DrawEllipse( Pens.Orange, bx, by, w, h );
					
					if( d != 1 ) {
						g.DrawEllipse( Pens.Red, bx - (d-5), by - (d-5), w + (d-5)*2, h + (d-5)*2 );
					}
				}
				else {
					g.DrawEllipse( Pens.DimGray, bx, by, w, h );
				}
			}
		}
	}
	
	//显示掌控板的display控件
	void ZK_display( Graphics g, int SX, int SY )
	{
		//g.DrawRectangle( Pens.White, SX + X, SY + Y, Width, Height );
		
		GraphicsState gs = g.Save();
		g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
		
		float PerW = Width / 128;
		float PerH = Height / 64;
		float DPerW = PerW * 0.8f;
		float DPerH = PerH * 0.8f;
		
		float w = DPerW;
		float h = DPerH;
		for( int i = 0; i < 16; ++i ) {
			for( int j = 0; j < 64; ++j ) {
				
				byte b = (byte)owner.DataList[i*64+j];
				
				float x = SX + X + (i + 1) * PerW * 8 - PerW;
				float y = SY + Y + j * PerH;
				
				Brush b1 = ZKBrush;
				Brush b0 = Brushes.White;
				
				if( (b & 0x01) != 0 ) g.FillRectangle( b0, x - PerW*0, y, w, h ); else g.FillRectangle( b1, x - PerW*0, y, w, h );
				if( (b & 0x02) != 0 ) g.FillRectangle( b0, x - PerW*1, y, w, h ); else g.FillRectangle( b1, x - PerW*1, y, w, h );
				if( (b & 0x04) != 0 ) g.FillRectangle( b0, x - PerW*2, y, w, h ); else g.FillRectangle( b1, x - PerW*2, y, w, h );
				if( (b & 0x08) != 0 ) g.FillRectangle( b0, x - PerW*3, y, w, h ); else g.FillRectangle( b1, x - PerW*3, y, w, h );
				if( (b & 0x10) != 0 ) g.FillRectangle( b0, x - PerW*4, y, w, h ); else g.FillRectangle( b1, x - PerW*4, y, w, h );
				if( (b & 0x20) != 0 ) g.FillRectangle( b0, x - PerW*5, y, w, h ); else g.FillRectangle( b1, x - PerW*5, y, w, h );
				if( (b & 0x40) != 0 ) g.FillRectangle( b0, x - PerW*6, y, w, h ); else g.FillRectangle( b1, x - PerW*6, y, w, h );
				if( (b & 0x80) != 0 ) g.FillRectangle( b0, x - PerW*7, y, w, h ); else g.FillRectangle( b1, x - PerW*7, y, w, h );
			}
		}
		g.Restore( gs );
	}
	
	//显示掌控板的display控件
	void ZK_rgb( Graphics g, int SX, int SY )
	{
		for( int i = 0; i < 3; ++i ) {
			
			SetColor( owner.DataList[i] );
			g.FillEllipse( BackBrush, SX + X + 4f + i * 18 - 1, SY + Y + 2.4f - 1, 10, 10 );
			g.FillEllipse( BackBrush1, SX + X + 4f + i * 18 - 4, SY + Y + 2.4f - 4, 16, 16 );
			g.FillEllipse( BackBrush2, SX + X + 4f + i * 18 - 6, SY + Y + 2.4f - 6, 20, 20 );
		}
	}
	
	//===================================================================================
	
	//显示一个点阵字符
	void DrawChar( Graphics g, int SX, int SY, char c, int Line, int Column )
	{
		//g.DrawString( c.ToString(), f, Brushes.WhiteSmoke, SX + X + Column*20*12/16-5, 100 + SY + Y + Line*20-5 );
		
		float tX = SX + X + Column*15f/1.006f + 0.6f;
		float tY = SY + Y + Line*24 + 2;
		
		if( c >= ' ' ) {
			c -= ' ';
		}
		else {
			c = (char)0;
		}
		//g.FillRectangle( DotCharBackBrush, tX, tY, 14, 20 );
		for( int i = 0; i < 5; ++i ) {
			byte b = n_DotChar.DotChar.DotSet[5*c + i];
			for( int n = 0; n < 8; ++n ) {
				float x = 0.5f + tX + i * 2.8f;
				float y =  tY + n * 2.8f;
				
				if( (b & 0x01) != 0 ) {
					g.FillRectangle( DotCharForeBrush, x, y, 2, 2 );
				}
				b >>= 1;
			}
		}
	}
	
	//显示一个点阵字符
	void DrawASCChar( Graphics g, int SX, int SY, char c, int Line, int Column )
	{
		//g.DrawString( c.ToString(), f, Brushes.WhiteSmoke, SX + X + Column*20*12/16-5, 100 + SY + Y + Line*20-5 );
		
		float tX = SX + X + Column*ST7920_SW + 0.6f;
		float tY = SY + Y + Line*ST7920_SW*2 + 2;
		
		//g.FillRectangle( DotCharBackBrush, tX, tY, 14, 20 );
		for( int i = 0; i < 16; ++i ) {
			byte b = n_SimCommon.SimCommon.GetAscii( c, i );
			for( int n = 0; n < 8; ++n ) {
				float x = tX + n * ST7920_PerW;
				float y =  tY + i * ST7920_PerW;
				
				if( (b & 0x80) != 0 ) {
					g.FillRectangle( Brushes.WhiteSmoke, x, y, 2, 2 );
				}
				else {
					g.FillRectangle( Brushes.DarkBlue, x, y, 2, 2 );
				}
				b &= 0x7F;
				b <<= 1;
			}
		}
	}
	
	//显示一个点阵字符
	void DrawHZChar( Graphics g, int SX, int SY, char c, int Line, int Column )
	{
		//g.DrawString( c.ToString(), f, Brushes.WhiteSmoke, SX + X + Column*20*12/16-5, 100 + SY + Y + Line*20-5 );
		
		float tX = SX + X + Column*ST7920_SW + 0.6f;
		float tY = SY + Y + Line*ST7920_SW*2 + 2;
		
		//g.FillRectangle( DotCharBackBrush, tX, tY, 14, 20 );
		for( int i = 0; i < 16; ++i ) {
			byte b = n_SimCommon.SimCommon.GetHzk( c, i*2 );
			for( int n = 0; n < 8; ++n ) {
				float x = tX + n * ST7920_PerW;
				float y =  tY + i * ST7920_PerW;
				
				if( (b & 0x80) != 0 ) {
					g.FillRectangle( Brushes.WhiteSmoke, x, y, 2, 2 );
				}
				else {
					g.FillRectangle( Brushes.DarkBlue, x, y, 2, 2 );
				}
				b &= 0x7F;
				b <<= 1;
			}
			b = n_SimCommon.SimCommon.GetHzk( c, i*2+1 );
			for( int n = 0; n < 8; ++n ) {
				float x = ST7920_SW + tX + n * ST7920_PerW;
				float y =  tY + i * ST7920_PerW;
				
				if( (b & 0x80) != 0 ) {
					g.FillRectangle( Brushes.WhiteSmoke, x, y, 2, 2 );
				}
				else {
					g.FillRectangle( Brushes.DarkBlue, x, y, 2, 2 );
				}
				b &= 0x7F;
				b <<= 1;
			}
		}
	}
	
	//显示
	public void DrawDot( Graphics g, int SX, int SY )
	{
		int Number = owner.DataList[1024];
		if( Number == 0 ) {
			Number = 1;
		}
		Number *= 8;
		
		//用于竖屏MAX7219
		if( Value1 == 1 ) {
			Number = 8;
		}
		
		for( int i = 0; i < Number; ++i ) {
			DrawDotOne( g, SX, SY, i );
		}
	}
	
	//显示
	public void DrawDotOne( Graphics g, int SX, int SY, int n )
	{
		float w = Width/8.7f;
		float h = Height/8.7f;
		
		int d = owner.DataList[n];
		
		for( int i = 0; i < 8; ++i ) {
			bool Bit = (d & 0x01) != 0;
			d >>= 1;
			if( Bit ) {
				float bx = SX + X + n*Width/7f - w/2;
				float by = SY + Y + i*Height/7f - h/2;
				g.FillEllipse( Brushes.Gold, bx, by, w, h );
			}
		}
	}
	
	//-------------------------------
	//显示MAX7219
	public void DrawDotMax7219( Graphics g, int SX, int SY )
	{
		int Value = owner.DataList[1024];
		int An = Value / 256;
		int Cn = Value % 256;
		
		if( Value1 == 1 ) {
			float xbc = Width/7;
			float ybc = Height/7;
			g.FillRectangle( T_MAX7219BackBrush, SX + X - xbc, SY + Y - ybc, An * (Width/7*8) + xbc, Cn / 8 * (Height/7*8) + ybc );
		}
		
		for( int i = 0; i < An; ++i ) {
			for( int j = 0; j < Cn; ++j ) {
				DrawDotOneMax7219( g, SX, SY, An, Cn, i, j );
			}
		}
	}
	
	//显示
	public void DrawDotOneMax7219( Graphics g, int SX, int SY, int An, int Cn, int xx, int yy )
	{
		float w = Width/8.7f;
		float h = Height/8.7f;
		
		int d = owner.DataList[(xx+1)*Cn - 1 - yy];
		
		for( int i = 0; i < 8; ++i ) {
			bool Bit = (d & 0x01) != 0;
			d >>= 1;
			if( Bit ) {
				float bx = SX + X + xx*(Width*8/7) + i*Width/7f - w/2;
				float by = SY + Y + yy*Height/7f - h/2;
				g.FillEllipse( Brushes.Gold, bx, by, w, h );
			}
		}
	}
	
	//-------------------------------
	//显示颜色
	public void DrawColor( Graphics g, int SX, int SY )
	{
		int c = owner.DataList[0];
		int a = owner.DataList[1];
		int b = owner.DataList[2];
		int s = owner.DataList[3];
		
		float xx = SX + X;
		float yy = SY + Y + Height;
		
		g.DrawString( "色调: " + a, n_GUIset.GUIset.ModuleNameFont, Brushes.Black, xx, yy + 0 );
		g.DrawString( "亮度: " + b, n_GUIset.GUIset.ModuleNameFont, Brushes.Black, xx, yy + 15 );
		g.DrawString( "饱和度: " + s, n_GUIset.GUIset.ModuleNameFont, Brushes.Black, xx, yy + 30 );
		g.DrawString( "颜色值: " + c, n_GUIset.GUIset.ModuleNameFont, Brushes.SlateGray, xx, yy + 45 );
		string mes = "分量: R-" + c/65536 + " G-" + (c%65536)/256 + " B-" + c%256;
		g.DrawString( mes, n_GUIset.GUIset.ModuleNameFont, Brushes.SlateGray, xx, yy + 60 );
		
		double an = a * Math.PI / 180;
		float px = (float)(Width*(1000-b)/2000 * Math.Sin( an ));
		float py = (float)(Height*(1000-b)/2000 * Math.Cos( an ));
		px = SX + X + Width/2 - px;
		py = SY + Y + Height/2 - py;
		g.DrawEllipse( Pens.WhiteSmoke, px - 6, py - 6, 12, 12 );
		g.DrawEllipse( Pens.Black, px - 7, py - 7, 14, 14 );
	}
	
	//-------------------------------
	//显示
	public void DrawSeg( Graphics g, int SX, int SY )
	{
		DrawSegOne( g, SX, SY, Value1, 0 );
		DrawSegOne( g, SX, SY, Value1, 1 );
		DrawSegOne( g, SX, SY, Value1, 2 );
		DrawSegOne( g, SX, SY, Value1, 3 );
	}
	
	//显示
	public void DrawSegOne( Graphics g, int SX, int SY, int BaseAddr, int n )
	{
		int d = owner.DataList[BaseAddr + n];
		
		for( int i = 0; i < 8; ++i ) {
			bool Bit = (d & 0x01) != 0;
			d >>= 1;
			if( Bit ) {
				float bx = SX + X + n*Width/4f;
				float by = SY + Y;
				
				if( i != 7 ) {
					g.DrawLine( SegPen, bx + PointList[i*4+0], by + PointList[i*4+1], bx + PointList[i*4+2], by + PointList[i*4+3] );
				}
				else {
					if( Value2 == 0 ) {
						g.FillEllipse( SegBrush, bx + PointList[i*4+0] - 1, by + PointList[i*4+1], (float)PointList[i*4+2]/2.9f, (float)PointList[i*4+3]/2.9f );
					}
					else {
						g.FillEllipse( SegBrush, bx + PointList[i*4+0] - 1, by + PointList[i*4+1] - 7, (float)PointList[i*4+2]/2.9f, (float)PointList[i*4+3]/2.9f );
						g.FillEllipse( SegBrush, bx + PointList[i*4+0] + 1, by + PointList[i*4+1] - 28, (float)PointList[i*4+2]/2.9f, (float)PointList[i*4+3]/2.9f );
					}
				}
			}
		}
	}
	
	//-------------------------------
	
	//设置颜色
	public void SetColor( int c )
	{
		int B = c & 0xFF; c >>= 8;
		int G = c & 0xFF; c >>= 8;
		int R = c & 0xFF;
		BackBrush.Color = Color.FromArgb( 150, R, G, B );
		BackBrush1.Color = Color.FromArgb( 100, R, G, B );
		BackBrush2.Color = Color.FromArgb( 50, R, G, B );
	}
	
	//设置值
	public void SetValue( string ss )
	{
		if( ss == null || ss == "" ) {
			return;
		}
		string[] s = ss.Split( ',' );
		
		for( int i = 0; i < s.Length; ++i ) {
			if( s[i].StartsWith( "0x" ) ) {
				s[i] = (int.Parse( s[i].Remove( 0, 2 ),System.Globalization.NumberStyles.HexNumber )).ToString();
			}
		}
		
		X = n_Data.Const.Parse( s[0] );
		Y = n_Data.Const.Parse( s[1] );
		Width = n_Data.Const.Parse( s[2] );
		Height = n_Data.Const.Parse( s[3] );
		if( s.Length >= 5 ) {
			SimType = n_Data.Const.Parse( s[4] );
			if( s.Length >= 6 ) {
				Value1 = n_Data.Const.Parse( s[5] );
				if( s.Length >= 7 ) {
					Value2 = n_Data.Const.Parse( s[6] );
					if( s.Length >= 8 ) {
						Value3 = n_Data.Const.Parse( s[7] );
					}
				}
			}
			if( SimType == T_Dot12864 ) {
				bitmap = new Bitmap( 128, 64 );
			}
			if( SimType == T_Dot12864_ST7920 ) {
				bitmap = new Bitmap( 128, 64 );
			}
			if( SimType == T_Dot12864_ST7565 ) {
				bitmap = new Bitmap( 128, 64 );
			}
			if( SimType == T_16X32 ) {
				bitmap = new Bitmap( 16, 32 );
			}
		}
		
		if( SimType >= IO_START && SimType <= IO_END && owner != null ) {
			owner.IO_Base = true;
		}
		
		float H = Height / 2;
		float W = Width/4;
		W = W * 135 / (135+118);
		float H2 = H * 2;
		
		float offx = Height/34;
		float offx2 = Height/17;
		
		// 60 195 313 -> 135,118
		
		PointList[0] = 0; PointList[1] = 0; PointList[2] = W; PointList[3] = 0;
		PointList[4] = W; PointList[5] = 0; PointList[6] = W - offx; PointList[7] = H;
		PointList[8] = W - offx; PointList[9] = H; PointList[10] = W - offx2; PointList[11] = H2;
		PointList[12] = W - offx2; PointList[13] = H2; PointList[14] = -offx2; PointList[15] = H2;
		PointList[16] = -offx; PointList[17] = H; PointList[18] =  -offx2; PointList[19] = H2;
		PointList[20] = 0; PointList[21] = 0; PointList[22] =  -offx; PointList[23] = H;
		PointList[24] = -offx; PointList[25] = H; PointList[26] = W - offx; PointList[27] = H;
		PointList[28] = W+4; PointList[29] = H2-2; PointList[30] = W; PointList[31] = W;
		
		
		SegPen.Width = (float)Width/36.2f; //原来是7
	}
	
	//转换到文字
	public string ToText()
	{
		return "//[Simulate] " + X + "," + Y + "," + Width + "," + Height + "," + SimType + "," + Value1 + "," + Value2 + "," + Value3 + ",\n";
	}
}
}


